package com.example.module.api;

import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;

import android.content.Context;
import android.util.Log;

import com.example.persistence.database.CardListHelper;
import com.example.util.StringUtil;
import com.google.gson.Gson;

public class CardSyncTask extends AsyncHttpTask {
	private int count;
	private int total;
	private static final String TAG = "CardSyncTask";
	
	private String cardPictureUrl, corporateCardPictureUrl;

	public CardSyncTask(Context context) {
		super(context);
	}

	@Override
	public HttpTaskReponse doRequest(APIRequest request) throws Exception {
		HttpGet httpRequest = new HttpGet(request.getURL());
		httpRequest.setHeader("Content-Type", "application/json");
		httpRequest.setHeader("SessionKey", mSessionKey);
		HttpResponse response = client.execute(httpRequest);

		HttpEntity resEntity = response.getEntity();
		String responseText = EntityUtils.toString(resEntity, HTTP.UTF_8);
		
		Log.d(TAG, "responseText=" + responseText);
		
		JSONObject result = new JSONObject(responseText);
		if (!result.has("LinkedCards")) {
			return new HttpTaskReponse(RESPONSE_FAIL, "There is no card");
		}
		
		ArrayList<Card> cards = new ArrayList<Card>();
		JSONArray cardArray = result.getJSONArray("LinkedCards");
		
		count = 0;
		total = cardArray.length() * 3;
		
		for (int i = 0; cardArray != null && i < cardArray.length(); i++) {
			Card card = new Gson().fromJson(((JSONObject) cardArray.get(i)).toString(), Card.class);
			Log.d(TAG, "card=" + card.toString());
			CardListHelper helper = new CardListHelper(mContext);
			Card localCard = helper.getCard(card.getCardToken());
			
			if (localCard == null) {
				downloadImageFiles(card);
			}
			else {
				String serverTimestamp = StringUtil.toTimestamp(card.getLastModifiedDate());
				String localTimestamp = StringUtil.toTimestamp(localCard.getLastModifiedDate());
				
				Log.d(TAG, "localTimestamp=" + localTimestamp + " < serverTimestamp=" + serverTimestamp);
				
				if (localTimestamp.compareTo(serverTimestamp) < 0) {
					downloadImageFiles(card);	
				}
				else {
					card.setFrontImage(localCard.getFrontImage());
					card.setBackImage(localCard.getBackImage());
					card.setCardImage(localCard.getCardImage());
					
					count += 3;
					publishProgress((count * 100) / total);
				}
			}
			
			cards.add(card);
		}
		
		CardListHelper helper = new CardListHelper(mContext);
		helper.insert(cards);
		
		return new HttpTaskReponse(RESPONSE_OK, "It has been completed to sync.");
	}

	private void downloadImageFiles(Card card) {
		if (StringUtil.isEmpty(card.getCardToken())) {
			String frontImageFileName = requestPicture(card.getCardToken(), true);
			Log.d(TAG, "frontImageFileName=" + frontImageFileName);
			
			if (frontImageFileName != null && !"".equals(frontImageFileName))
				card.setFrontImage(frontImageFileName);	
		}
		count++;
		publishProgress((count * 100) / total);
		
		if (StringUtil.isEmpty(card.getCardToken())) {
			String backImageFileName = requestPicture(card.getCardToken(), false);
			Log.d(TAG, "backImageFileName=" + backImageFileName);
			
			if (backImageFileName != null && !"".equals(backImageFileName)) {
				card.setBackImage(backImageFileName);	
			}
		}
		count++;
		publishProgress((count * 100) / total);
		
		if (StringUtil.isEmpty(card.getCorporateCardPictureId())) {
			String cardImageFileName = requestPicture(card.getCorporateId(), card.getCorporateCardPictureId());
			Log.d(TAG, "cardImageFileName=" + cardImageFileName);
			
			if (cardImageFileName != null && !"".equals(cardImageFileName)) {
				card.setCardImage(cardImageFileName);	
			}
		}
		count++;
		publishProgress((count * 100) / total);
	}
	
	private String requestPicture(String cardToken, boolean isFront) {
		try {
			HttpPost post = new HttpPost(getCardPictureUrl());
			post.setHeader("Content-Type", "application/json");
			post.setHeader("SessionKey", mSessionKey);
			
			JSONObject jsonObj = new JSONObject("{'CardToken':'" + cardToken + "','FrontCardPicture':" + isFront + "}");
			
			Log.d(TAG, "requestPicture jsonObj=" + jsonObj);
			
			post.setEntity(new StringEntity(jsonObj.toString(), HTTP.UTF_8));
			HttpResponse httpResponse = client.execute(post);
			
			
			if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				HttpEntity responseEntity = httpResponse.getEntity();
				if (responseEntity != null && responseEntity.getContentLength() > 0) {
					if (isFront)
						return toImageFile(responseEntity, cardToken + "_front");
					else
						return toImageFile(responseEntity, cardToken + "_back");
				}
			}	
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		
		return "";
	}
	
	private String requestPicture(String corporateId, String corporateCardPictureId) {
		try {
			HttpPost post = new HttpPost(getCorporateCardPictureUrl());
			post.setHeader("Content-Type", "application/json");
			post.setHeader("SessionKey", mSessionKey);
			
			JSONObject jsonObj = new JSONObject("{'CardPictureId':'" + corporateCardPictureId + "','CorporateId':'" + corporateId + "'}");
			
			Log.d(TAG, "cardPictureUrl=" + cardPictureUrl);
			Log.d(TAG, "requestPicture jsonObj=" + jsonObj.toString());
			
			post.setEntity(new StringEntity(jsonObj.toString(), HTTP.UTF_8));
			HttpResponse httpResponse = client.execute(post);
			
			if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				HttpEntity responseEntity = httpResponse.getEntity();
				if (responseEntity != null && responseEntity.getContentLength() > 0) {
					return toImageFile(responseEntity, corporateId + "_" + corporateCardPictureId);
				}
			}	
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		
		return "";
	}

	public String getCardPictureUrl() {
		return cardPictureUrl;
	}

	public void setCardPictureUrl(String cardPictureUrl) {
		this.cardPictureUrl = cardPictureUrl;
	}

	public String getCorporateCardPictureUrl() {
		return corporateCardPictureUrl;
	}

	public void setCorporateCardPictureUrl(String corporateCardPictureUrl) {
		this.corporateCardPictureUrl = corporateCardPictureUrl;
	}
}
